/*
 * UnaryExpression.java
 * 
 * last update: 16.01.2010 by Stefan Saru
 * 
 * author:	Power(power@kermit.cs.pub.ro)
 * 
 * Obs:
 */

package engine;

class UnaryExpression extends Expression{
	final static int UNARY_PLUS   = 0;
	final static int BITWISE_NOT  = 1;
	final static int BITWISE_OR   = 2;
	final static int BITWISE_NOR  = 3;
	final static int BITWISE_AND  = 4;
	final static int BITWISE_NAND = 5;
	final static int BITWISE_XOR  = 6;
	final static int BITWISE_NXOR = 7;
	final static int UNARY_MINUS  = 8;
	final static int LOGICAL_NOT  = 9;

	public int op;
	Expression exp;

	String [] opStrings = {" +", " ~ ", " | ", " ~| ", " & ", " ~& ", " ^ ", " ~^ ", " -", " !"};

	UnaryExpression(NameSpace ns, String oper, Expression exp){
		super(ns);
		if (oper.equals("+")) op = UNARY_PLUS;
		else if (oper.equals("-")) op = UNARY_MINUS;
		else if (oper.equals("~")) op = BITWISE_NOT;
		else if (oper.equals("|")) op = BITWISE_OR;
		else if (oper.equals("~|")) op = BITWISE_NOR;
		else if (oper.equals("&")) op = BITWISE_AND;
		else if (oper.equals("~&")) op = BITWISE_NAND;
		else if (oper.equals("^")) op = BITWISE_XOR;
		else if (oper.equals("~^")) op = BITWISE_NXOR;
		else if (oper.equals("!")) op = LOGICAL_NOT;
		else throw new Error("UnaryExpression.<init> : Unknown operator: " + oper);
		this.exp = exp;

		switch (op) {
		case UNARY_PLUS: 
		case UNARY_MINUS:
		case LOGICAL_NOT:
			length = exp.length;
			break;
		case BITWISE_NOT:
		case BITWISE_OR:
		case BITWISE_NOR:
		case BITWISE_AND:
		case BITWISE_NAND:
		case BITWISE_XOR:
		case BITWISE_NXOR:
			length = 1;
			break;
		default:
			throw new Error("UNaryExpression.<init> : unknown operator " + op);
		}
	}

	public Result evaluate()
	throws InterpretTimeException
	{
		Result result = exp.evaluate();
		switch (op) {
		case UNARY_PLUS: 
			break;
		case UNARY_MINUS:
			result.neg();
			break;
		case LOGICAL_NOT:
			result.lNot();
		case BITWISE_NOT:
			result.bNot();
			break;
		case BITWISE_OR:
			result.bOrR();
			break;
		case BITWISE_NOR:
			result.bNOrR();
			break;
		case BITWISE_AND:
			result.bAndR();
			break;
		case BITWISE_NAND:
			result.bNAndR();
			break;
		case BITWISE_XOR:
			result.bXOrR();
			break;
		case BITWISE_NXOR:
			result.bNXOrR();
			break;
		default:
			throw new Error("UnaryExpression.evaluate() : unknown operator" + op);
		}
		return result;
	}

	void addMonitor(Monitor m){
		exp.addMonitor(m);
	}

	public String toString(){
		return opStrings[op] + exp;
	}

	public boolean isLeftValue(){
		return false;
	}
}
